<?php
namespace hangpu8\hpcms\Utils;

use Exception;
use hg\apidoc\parseApi\ParseAnnotation;
use think\facade\Cache;
use think\facade\Config;

class Router
{
    
    /**
     * 获得所有路由
     *
     * @param boolean $isCache true重新缓存，false使用缓存
     * @return array
     */
    public function getRouterAll($isCache = false) : array
    {
        $apidocConfig = Config::get("apidoc") ? Config::get("apidoc") : Config::get("apidoc.");
        
        $appAll = $apidocConfig['apps'];
        $moduleRouter = [];
        foreach ($appAll as $value)
        {
            if($value['folder'])
            {
                $route = $this->getRouter($value['folder']);
                $moduleRouter = array_merge($moduleRouter,$route);
            }
        }

        // 获取配置路由
        $hpcmsConfig = Config::get("hpcms") ? Config::get("hpcms") : Config::get("hpcms.");
        if(!$hpcmsConfig){
            throw new Exception("获取Hpcms配置文件失败");
        }
        $hpCmsConfigRoutes = $this->getHpcmsRouter($hpcmsConfig['routes']);

        // 获取数据表内容
        $routeList = $this->getDbRoutes($isCache);

        // 组合双向路由
        $routes = array_merge($moduleRouter,$hpCmsConfigRoutes,$routeList);

        // 返回全部路由
        return $routes;
    }

    /**
     * 获取数据表路由
     *
     * @param boolean $isCache true重新缓存，false使用缓存
     * @return array
     */
    private function getDbRoutes($isCache = false) : array
    {
        // 查询缓存并返回
        $routes = Cache::get('route_list') ? Cache::get('route_list') : [];
        if ($routes && !$isCache)
        {
            return $routes;
        }
        // 查询数据并缓存
        $service = new \hangpu8\hpcms\service\AuthRule;
        $routes = $service->getRoutes();
        Cache::set('route_list',$routes);

        // 返回数据
        return $routes;
    }

    /**
     * 获取配置路由
     *
     * @param array $data
     * @return array
     */
    private function getHpcmsRouter(array $data) : array
    {
        $routes = [];
        foreach ($data as $value)
        {
            // 取得版本号
            $prefix = substr($value['url'],0,strrpos($value['url'] ,"."));
            $version = basename($prefix);
            $routes[] = [
                'router'                => $value['url'],
                'method'                => $value['method'],
                'namespace'             => $value['namespace'],
                'version'               => $version,
            ];
        }
        return $routes;
    }

    /**
     * 获取模块路由
     *
     * @param string $module
     * @return void
     */
    private function getRouter(string $module) : array
    {
        $res = (new ParseAnnotation())->renderApiData($module);
        $data = $res['data'];
        if (empty($data))
        {
            return [];
        }
        $routes = [];
        foreach ($data as $value)
        {
            $controller = $value['controller'];
            if (!empty($value['children']))
            {
                foreach ($value['children'] as $value2)
                {
                    // 取得版本号
                    $prefix = substr($value2['url'],0,strrpos($value2['url'] ,"."));
                    $version = basename($prefix);
                    // 取得URL路由
                    $action = $value2['name'];

                    // 拆分多种请求路由
                    $methods = explode(',',$value2['method']);
                    if (count($methods) > 1)
                    {
                        foreach ($methods as $value3)
                        {
                            // 截取路由中的api
                            $routerApi = str_replace('api/','',$value2['url']);
                            // 拼接命名空间
                            $namespace = "app\\{$module}\\controller\\{$version}\\{$controller}@{$action}";
                            $routes[] = [
                                'router'                => $routerApi,
                                'method'                => $value3,
                                'namespace'             => $namespace,
                                'version'               => $version,
                            ];
                        }
                    }else{
                        // 截取路由中的api
                        $routerApi = str_replace('api/','',$value2['url']);
                        // 拼接命名空间
                        $namespace = "app\\{$module}\\controller\\{$version}\\{$controller}@{$action}";
                        $routes[] = [
                            'router'                => $routerApi,
                            'method'                => $value2['method'],
                            'namespace'             => $namespace,
                            'version'               => $version,
                        ];
                    }
                }
            }
        }
        return $routes;
    }
}